package com.lswms.service.impl;

import cn.hutool.core.date.DateUtil;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import com.lswms.common.exception.ErrorCode;
import com.lswms.common.exception.RenException;
import com.lswms.common.page.PageInfo;
import com.lswms.common.page.PageRequest;
import com.lswms.common.service.impl.CrudServiceImpl;
import com.lswms.common.utils.ConvertUtils;
import com.lswms.common.utils.MoneyUtil;
import com.lswms.common.utils.OpenDoubleQiu;
import com.lswms.common.utils.ZqDateUtil;
import com.lswms.dao.YnLotteryTicketOrderDao;
import com.lswms.dto.YnLotteryTicketOrderDTO;
import com.lswms.dto.YnLotteryTicketResultDTO;
import com.lswms.dto.vo.req.DeleteMyNumsReq;
import com.lswms.dto.vo.req.DoubleBallDetailReq;
import com.lswms.dto.vo.req.MyLotteryTicketReq;
import com.lswms.dto.vo.req.MyNumsReq;
import com.lswms.dto.vo.req.PayReq;
import com.lswms.dto.vo.req.SaveNumReq;
import com.lswms.dto.vo.req.SetXCountReq;
import com.lswms.dto.vo.resp.DoubleBallDetailResp;
import com.lswms.dto.vo.resp.MyNumsDetailResp;
import com.lswms.dto.vo.resp.MyNumsResp;
import com.lswms.dto.vo.resp.NewOpenLotteryResp;
import com.lswms.entity.YnLotteryTicketActivityEntity;
import com.lswms.entity.YnLotteryTicketOrderEntity;
import com.lswms.entity.YnLotteryTicketResultEntity;
import com.lswms.entity.YnPayRecordEntity;
import com.lswms.entity.YnUserEntity;
import com.lswms.service.YnLotteryTicketOrderService;
import com.lswms.service.YnLotteryTicketResultService;
import com.lswms.service.YnPayRecordService;
import com.lswms.service.YnUserService;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import lombok.extern.slf4j.Slf4j;

/**
 * 彩票下单记录
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2020-06-20
 */
@Service
@Slf4j
public class YnLotteryTicketOrderServiceImpl extends CrudServiceImpl<YnLotteryTicketOrderDao, YnLotteryTicketOrderEntity, YnLotteryTicketOrderDTO> implements YnLotteryTicketOrderService {

	
	@Autowired
	private YnUserService ynUserService;
	
	@Autowired
	private YnLotteryTicketResultService ynLotteryTicketResultService;
	
	@Autowired
	private YnPayRecordService ynPayRecordService;


	
    @Override
    public QueryWrapper<YnLotteryTicketOrderEntity> getWrapper(Map<String, Object> params){
        String id = (String)params.get("id");

        QueryWrapper<YnLotteryTicketOrderEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id);

        return wrapper;
    }

	/**
	 * 保存号码
	 */
	@Override
	public String saveNum(SaveNumReq req,YnUserEntity ynuser) {
		log.info("保存号码，req:{},ynuser:{}",JSON.toJSONString(req),JSON.toJSONString(ynuser));
		
		YnLotteryTicketOrderEntity entity = new YnLotteryTicketOrderEntity();
		entity.setUserId(ynuser.getId());
		entity.setTicketNo(req.getTicket_no());
		entity.setRedBall(req.getRed_ball());
		entity.setBlueBall(req.getBlue_ball());
		entity.setType(Integer.parseInt(req.getType()));
		entity.setStatus(0);
		entity.setXCount(Integer.parseInt(req.getX_count()));
		entity.setCreateDate(ZqDateUtil.getNow());
		//计算金额
		BigDecimal totalAmount = new BigDecimal(req.getX_count()).multiply(new BigDecimal(2500));
		entity.setTotalAmount(totalAmount);
		baseDao.insert(entity);
		return entity.getId()+"";
	}

	/**
	 * 支付
	 */
	@Override
	public void pay(PayReq req,YnUserEntity ynuser) {
		log.info("支付，参数:{}",JSON.toJSONString(req));
		String orderId = req.getOrderId();
		//YnUserEntity ynuser = ynUserService.selectById(record.getUserId());
		//判断是否可投
		DoubleBallDetailReq detailReq = new DoubleBallDetailReq();
		detailReq.setType("1");
		DoubleBallDetailResp detailssq = ynLotteryTicketResultService.doubleBallDetail(detailReq);
		//判断是否可投
		detailReq.setType("2");
		DoubleBallDetailResp detailplw = ynLotteryTicketResultService.doubleBallDetail(detailReq);

		//奖励金
		BigDecimal reward = ynuser.getReward();
		//余额
		BigDecimal balance = ynuser.getBalance();
		BigDecimal totalBalance = reward.add(balance);
		//查询总订单金额
		BigDecimal totalAmount = BigDecimal.ZERO;
		//可以购买的订单id
		List<String> orderIdList = new ArrayList<String>();
		for(int i = 0;i<orderId.split(",").length;i++){
			String id = orderId.split(",")[i];
			YnLotteryTicketOrderEntity entity = baseDao.selectById(Long.parseLong(id));
			if(entity != null){
				if(entity.getStatus() == 0){
					//双色球可投
					if(entity.getType() == 1 && "1".equals(detailssq.getStatus())){
						totalAmount = totalAmount.add(entity.getTotalAmount());
						orderIdList.add(id);
					}else if(entity.getType() == 2 && "1".equals(detailplw.getStatus())){
						totalAmount = totalAmount.add(entity.getTotalAmount());
						orderIdList.add(id);
					}
				}
			}
		}
		//判断金额
		if(totalAmount.compareTo(totalBalance) > 0){
			throw new RenException(ErrorCode.AMOUNT_IS_LESS);
		}
		//修改订单状态
		for(String id : orderIdList){
			YnLotteryTicketOrderEntity entity = baseDao.selectById(Long.parseLong(id));
			YnUserEntity user = ynUserService.selectById(ynuser.getId());
			//奖励金
			BigDecimal rewardu = user.getReward();
			//余额
			BigDecimal balanceu = user.getBalance();
			//订单总金额
			BigDecimal orderAmount = entity.getTotalAmount();
			
			//剩余奖励金额
			BigDecimal rewardBalance = BigDecimal.ZERO;
			BigDecimal balanceBalance = BigDecimal.ZERO;
			
			//订单使用奖励金多少
			BigDecimal rewardUse = BigDecimal.ZERO;
			//订单使用余额多少
			BigDecimal balanceUse = BigDecimal.ZERO;
			
			//奖励金额大于0优先使用
			if(rewardu.compareTo(BigDecimal.ZERO) > 0){
				//判断奖励金额够用
				if(rewardu.compareTo(orderAmount) >= 0){
					rewardUse = orderAmount;
					rewardBalance = rewardu.subtract(rewardUse);
					balanceBalance = balanceu;
					balanceUse = BigDecimal.ZERO;
				//不够用
				}else{
					rewardUse = rewardu;
					rewardBalance = BigDecimal.ZERO;
					balanceUse = orderAmount.subtract(rewardUse);
					balanceBalance = balanceu.subtract(balanceUse);
				}
			//没有奖励金额
			}else{
				rewardUse = BigDecimal.ZERO;;
				rewardBalance = BigDecimal.ZERO;
				balanceUse = orderAmount;
				balanceBalance = balanceu.subtract(orderAmount);
			}
			//更新订单状态
			YnLotteryTicketOrderEntity entitys = new YnLotteryTicketOrderEntity();
			entitys.setId(Long.parseLong(id));
			entitys.setStatus(1);
			entitys.setAmount(balanceUse);
			entitys.setRewardAmount(rewardUse);
			entitys.setUpdateDate(ZqDateUtil.getNow());
			baseDao.updateById(entitys);
			//更新用户金额
			YnUserEntity users = new YnUserEntity();
			users.setId(ynuser.getId());
			users.setBalance(balanceBalance);
			users.setReward(rewardBalance);
			users.setUpdateDate(ZqDateUtil.getNow());
			ynUserService.updateById(users);
			//交易记录
			YnPayRecordEntity pay = new YnPayRecordEntity();
			pay.setUserId(ynuser.getId());
			pay.setBusinessType("LOTTERY_TICKET");
			pay.setType("bank");
			pay.setUuid(UUID.randomUUID().toString().replaceAll("-", ""));
			pay.setBusinessId(Long.parseLong(id));
			pay.setChannel("app");
			pay.setAmt(entity.getTotalAmount());
			pay.setStatus(1);
			pay.setRemark("余额或者奖励金购买彩票");
			pay.setYearmonth(ZqDateUtil.yyyy_MM());
			pay.setCreateDate(ZqDateUtil.getNow());
			pay.setUpdateDate(ZqDateUtil.getNow());
			ynPayRecordService.insert(pay);
		}
	}

	/**
	 * 修改倍数
	 */
	@Override
	public void setXCount(SetXCountReq req, YnUserEntity ynuser) {
		log.info("修改倍数，参数req:{},ynuser:{}",JSON.toJSONString(req),JSON.toJSONString(ynuser));
		//查询订单
		YnLotteryTicketOrderEntity entity = baseDao.selectById(Long.parseLong(req.getOrderId()));
		if(entity == null){
			throw new RenException(ErrorCode.ORDER_IS_NOEXIST);
		}
		String uid = entity.getUserId()+"";
		if(!uid.equals(ynuser.getId()+"")){
			throw new RenException(ErrorCode.MESSAGE_IS_ERROR);
		}
		if(new BigDecimal(req.getX_count()).compareTo(BigDecimal.ZERO) <= 0){
			throw new RenException(ErrorCode.X_COUNT_LESS_ONE);
		}
		if(entity.getStatus() != 0){
			throw new RenException(ErrorCode.NO_EDIT_ORDER);
		}
		//修改倍数
		YnLotteryTicketOrderEntity entitys = new YnLotteryTicketOrderEntity();
		entitys.setId(Long.parseLong(req.getOrderId()));
		entitys.setXCount(Integer.parseInt(req.getX_count()));
		entitys.setUpdateDate(ZqDateUtil.getNow());
		//计算金额
		BigDecimal totalAmount = new BigDecimal(req.getX_count()).multiply(new BigDecimal(2500));
		entitys.setTotalAmount(totalAmount);
		baseDao.updateById(entitys);
	}

	/**
	 * 我的选号
	 */
	@Override
	public PageInfo<MyNumsResp> myNums(MyNumsReq req, YnUserEntity ynuser) {
		log.info("我的选号，参数req:{}",JSON.toJSONString(req));
        QueryWrapper<YnLotteryTicketOrderEntity> wrapper = new QueryWrapper<>();
		wrapper.eq("user_id", ynuser.getId());
		wrapper.eq("status", 0);
		if(!"0".equals(req.getType())){
			wrapper.eq("type", req.getType());	
		}
		
		wrapper.groupBy("ticket_no","type");
        
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("page", req.getPageNo());
        params.put("limit", req.getPageSize());

		IPage<YnLotteryTicketOrderEntity> pageInfo = baseDao.selectPage(getPage(params, "ticket_no", false),wrapper);
		
		List<MyNumsResp> list = new ArrayList<MyNumsResp>();
		for(YnLotteryTicketOrderEntity entity : pageInfo.getRecords()){
			MyNumsResp resp = new MyNumsResp();
			resp.setId(entity.getId()+"");
			//查询是否过期
			Map<String, Object> mapParams = new HashMap<String, Object>();
			mapParams.put("ticket_no", entity.getTicketNo());
			List<YnLotteryTicketResultDTO> listDto = ynLotteryTicketResultService.list(mapParams);
			if(listDto != null && listDto.size() > 0){
				resp.setStatus("0");
			}else{
				DoubleBallDetailReq detailReq = new DoubleBallDetailReq();
				if(entity.getType() == 1){
					//判断是否可投
					detailReq.setType("1");
					DoubleBallDetailResp detailssq = ynLotteryTicketResultService.doubleBallDetail(detailReq);
					resp.setStatus(detailssq.getStatus());
				}else if(entity.getType() == 2){
					//判断是否可投
					detailReq.setType("2");
					DoubleBallDetailResp detailplw = ynLotteryTicketResultService.doubleBallDetail(detailReq);
					resp.setStatus(detailplw.getStatus());
				}
			}
			resp.setTicket_no(entity.getTicketNo());
			resp.setType(entity.getType()+"");
			//根据期数查询订单
			QueryWrapper<YnLotteryTicketOrderEntity> wrapper1 = new QueryWrapper<YnLotteryTicketOrderEntity>();
			wrapper1.eq("ticket_no", entity.getTicketNo());
			wrapper1.eq("user_id", ynuser.getId());
			wrapper1.eq("status", 0);
			wrapper1.eq("type", entity.getType());
			List<YnLotteryTicketOrderEntity> order = baseDao.selectList(wrapper1);
			
			BigDecimal amount = BigDecimal.ZERO;
			List<MyNumsDetailResp> lists = new ArrayList<MyNumsDetailResp>();
			for(YnLotteryTicketOrderEntity ti : order){
				MyNumsDetailResp re = new MyNumsDetailResp();
				re.setId(ti.getId()+"");
				re.setRed_ball(ti.getRedBall());
				re.setBlue_ball(ti.getBlueBall());
				re.setXCount(ti.getXCount()+"");
				
				lists.add(re);
				
				amount = amount.add(ti.getTotalAmount());	
			}
			resp.setAmount(MoneyUtil.bigDecimal2String(amount, 0));
			resp.setCount(order.size()+"");
			resp.setList(lists);
			list.add(resp);
		}
		
		PageInfo<MyNumsResp> pageList = new PageInfo<MyNumsResp>();
		pageList.setCount(pageInfo.getTotal());
		pageList.setList(list);
		pageList.setPageNo(Long.parseLong(req.getPageNo()));
		pageList.setPages(pageInfo.getPages());
		pageList.setPageSize(Long.parseLong(req.getPageSize()));
		log.info("我的选号，结果:{}",JSON.toJSONString(pageList));
		return pageList;
	}

	/**
	 * 我的彩票
	 */
	@Override
	public PageInfo<MyNumsResp> myLotteryTicket(MyLotteryTicketReq req,
			YnUserEntity ynuser) {
		log.info("我的彩票，参数req:{}",JSON.toJSONString(req));
		String level = "Hadiah utama,Hadiah kedua,Hadiah ketiga,Hadiah keempat,Hadiah kelima,Hadiah keenam";
		queryMyTicket(ynuser.getId());
		//状态（0全部，1待开奖，2已开奖，3中奖）
		String status = req.getStatus();
		
        QueryWrapper<YnLotteryTicketOrderEntity> wrapper = new QueryWrapper<>();
		wrapper.eq("user_id", ynuser.getId());
		if("0".equals(status)){
			wrapper.ne("status", 0);
		}else if("1".equals(status)){
			wrapper.eq("status", 1);
		}else if("2".equals(status)){
			List<Integer> list = new ArrayList<Integer>();
			list.add(2);
			list.add(3);
			wrapper.in("status", list);
		}else if("3".equals(status)){
			wrapper.eq("status", 2);
		}
		wrapper.groupBy("ticket_no","type");
        
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("page", req.getPageNo());
        params.put("limit", req.getPageSize());

		IPage<YnLotteryTicketOrderEntity> pageInfo = baseDao.selectPage(getPage(params, "ticket_no", false),wrapper);
		
		List<MyNumsResp> list = new ArrayList<MyNumsResp>();
		for(YnLotteryTicketOrderEntity entity : pageInfo.getRecords()){
			
			MyNumsResp resp = new MyNumsResp();
			resp.setId(entity.getId()+"");
			resp.setTicket_no(entity.getTicketNo());
			resp.setType(entity.getType()+"");
			Map<String, Object> mapParams = new HashMap<String, Object>();
			mapParams.put("ticket_no", entity.getTicketNo());
			mapParams.put("type", entity.getType());
			List<YnLotteryTicketResultDTO> listDto = ynLotteryTicketResultService.list(mapParams);
			if(listDto != null && listDto.size() > 0){
				YnLotteryTicketResultDTO dto = listDto.get(0);
				resp.setRed_ball(dto.getRedBall());
				resp.setBlue_ball(dto.getBlueBall());
			}
			//是否开奖1待开奖，2已中奖，3未中奖
			String isOpen = "3";

			//根据期数查询订单
			QueryWrapper<YnLotteryTicketOrderEntity> wrapper1 = new QueryWrapper<YnLotteryTicketOrderEntity>();
			wrapper1.eq("ticket_no", entity.getTicketNo());
			wrapper1.eq("user_id", ynuser.getId());
			wrapper1.eq("type", entity.getType());
			wrapper1.ne("status", 0);
			List<YnLotteryTicketOrderEntity> order = baseDao.selectList(wrapper1);
			
			BigDecimal amount = BigDecimal.ZERO;
			List<MyNumsDetailResp> lists = new ArrayList<MyNumsDetailResp>();
			for(YnLotteryTicketOrderEntity ti : order){
				MyNumsDetailResp re = new MyNumsDetailResp();
				re.setId(ti.getId()+"");
				re.setRed_ball(ti.getRedBall());
				re.setBlue_ball(ti.getBlueBall());
				re.setXCount(ti.getXCount()+"");
				re.setLotteryStatus(ti.getStatus()+"");
				if(ti.getStatus() == 2){
					re.setLevel(level.split(",")[ti.getLevel()-1]);
					re.setReward(MoneyUtil.bigDecimal2String(ti.getReward(), 2));
					isOpen = "2";
				}
				lists.add(re);
				
				amount = amount.add(ti.getTotalAmount());	
			}
			resp.setAmount(MoneyUtil.bigDecimal2String(amount, 0));
			resp.setCount(order.size()+"");
			resp.setLotteryStatus(isOpen);
			
			resp.setList(lists);
			list.add(resp);
		}
		
		PageInfo<MyNumsResp> pageList = new PageInfo<MyNumsResp>();
		pageList.setCount(pageInfo.getTotal());
		pageList.setList(list);
		pageList.setPageNo(Long.parseLong(req.getPageNo()));
		pageList.setPages(pageInfo.getPages());
		pageList.setPageSize(Long.parseLong(req.getPageSize()));
		log.info("我的选号，结果:{}",JSON.toJSONString(pageList));
		return pageList;
	}
	/**
	 * 查询列表前查询我的彩票是否中奖（更新）
	 */
	public void queryMyTicket(Long user_id){
        QueryWrapper<YnLotteryTicketOrderEntity> wrapper = new QueryWrapper<>();
		wrapper.eq("user_id", user_id);
		wrapper.eq("status", 1);
		List<YnLotteryTicketOrderEntity> order = baseDao.selectList(wrapper);
		//用户信息
		YnUserEntity user = ynUserService.selectById(user_id);
		for(YnLotteryTicketOrderEntity entity : order){
			String ticket_no = entity.getTicketNo();
			//查询这期是否开奖
			Map<String, Object> mapParams = new HashMap<String, Object>();
			mapParams.put("ticket_no", ticket_no);
			mapParams.put("type", entity.getType());
			List<YnLotteryTicketResultDTO> listDto = ynLotteryTicketResultService.list(mapParams);
			if(listDto != null && listDto.size() > 0){
				YnLotteryTicketResultDTO dto = listDto.get(0);
				String red = dto.getRedBall();
				String blue = dto.getBlueBall();
				
		        //2中奖，3未中奖
		        int status = 3;
		        //中奖金额
		        BigDecimal reward = BigDecimal.ZERO;
		        int level = 0;
		        String type = "";
				//双色球
				if(entity.getType() == 1){
					//判断是否中奖
			    	OpenDoubleQiu e1=new OpenDoubleQiu(entity.getRedBall(),entity.getBlueBall(),entity.getUserId()+"");
			        OpenDoubleQiu drawLottery=new OpenDoubleQiu(red,blue,"drawLottery");
			        level = OpenDoubleQiu.openAward(drawLottery,e1);
			        if(level > 0){
			        	status = 2;
			        }
			        if(level == 1){
			        	reward = dto.getLevelAmount1();
			        }else if(level == 2){
			        	reward = dto.getLevelAmount2();
			        }else if(level == 3){
			        	reward = dto.getLevelAmount3();
			        }else if(level == 4){
			        	reward = dto.getLevelAmount4();
			        }else if(level == 5){
			        	reward = dto.getLevelAmount5();
			        }else if(level == 6){
			        	reward = dto.getLevelAmount6();
			        }
			        type = "双色球";
				//排列五
				}else{
					if(red.equals(entity.getRedBall())){
						status = 2;
						level = 1;
						reward = dto.getLevelAmount1();
					}
					type = "排列五";
				}
				reward = reward.multiply(new BigDecimal(2500));
		        
	        	//更新订单状态
	        	YnLotteryTicketOrderEntity entitys = new YnLotteryTicketOrderEntity();
	        	entitys.setId(entity.getId());
	        	entitys.setStatus(status);
	        	entitys.setLevel(level);
	        	entitys.setReward(reward);
	        	entitys.setUpdateDate(ZqDateUtil.getNow());
	        	baseDao.updateById(entitys);
	        	if(status == 2){
		        	//添加交易记录
					YnPayRecordEntity pay = new YnPayRecordEntity();
					pay.setUserId(entity.getUserId());
					pay.setBusinessType("LOTTERY_TICKET_REWARD");
					pay.setType("bank");
					pay.setUuid(UUID.randomUUID().toString().replaceAll("-", ""));
					pay.setBusinessId(entity.getId());
					pay.setChannel("app");
					pay.setAmt(reward);
					pay.setStatus(1);
					pay.setRemark("彩票中奖"+type);
					pay.setYearmonth(ZqDateUtil.yyyy_MM());
					pay.setCreateDate(ZqDateUtil.getNow());
					pay.setUpdateDate(ZqDateUtil.getNow());
					ynPayRecordService.insert(pay);
					//更新用户金额
					BigDecimal balanceBalance = user.getBalance().add(reward);
					YnUserEntity users = new YnUserEntity();
					users.setId(entity.getUserId());
					users.setBalance(balanceBalance);
					users.setUpdateDate(ZqDateUtil.getNow());
					ynUserService.updateById(users);
	        	}
			}
		}
	}
	/**
	 * 我的选号删除
	 */
	@Override
	public void deleteMyNums(DeleteMyNumsReq dto, YnUserEntity ynuser) {
		
		YnLotteryTicketOrderEntity entity = baseDao.selectById(Long.parseLong(dto.getId()));
		if(entity == null){
			throw new RenException(ErrorCode.ORDER_IS_NOEXIST);
		}
		String uid = entity.getUserId()+"";
		if(!uid.equals(ynuser.getId()+"")){
			throw new RenException(ErrorCode.MESSAGE_IS_ERROR);
		}
		baseDao.deleteById(Long.parseLong(dto.getId()));
	}

	/**
	 * 每日数据
	 */
	@Override
	public String odata(String s, String e) {
        QueryWrapper<YnLotteryTicketOrderEntity> wrapper = new QueryWrapper<>();
		wrapper.ge("create_date", s);
		wrapper.le("create_date", e);
		List<YnLotteryTicketOrderEntity> order = baseDao.selectList(wrapper);
		int size = order.size();
		
		wrapper.groupBy("user_id");
		List<YnLotteryTicketOrderEntity> order1 = baseDao.selectList(wrapper);
		int size1 = order1.size();
		return size+","+size1;
	}
}